package com.xinyue.server.framework.codec;

import com.xinyue.server.framework.common.GameFrameworkConfig;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

/**
 * 响应消息缓存管理，客户端请求的消息返回时，在这里缓存一下，如果客户端长时间未收到服务器的响应消息，就会重新发送请求，如果缓存已存在，直接返回即可。
 *
 * @author 王广帅
 * @since 2022/1/23 14:11
 */
public class GameMessageResponseManager {
    private GameFrameworkConfig config;
    private long requestId;
    private ByteBuf byteBuf;
    private long startTime;
    private ChannelHandlerContext ctx;

    public void bindChannel(ChannelHandlerContext ctx) {
        this.ctx = ctx;
    }

    public void setNewCacheMsg(long requestId, ByteBuf byteBuf) {
        if (requestId < 0) {
            return;
        }
        clearCache();
        this.byteBuf = byteBuf;
        this.requestId = requestId;
    }

    private void checkExpire() {
        if (isCacheExpire()) {
            this.resetCache();
        }
    }

    private void resetCache() {
        clearCache();
        this.startTime = 0;
        this.requestId = 0;
    }

    public void clearCache() {
        if (this.byteBuf != null) {
            ReferenceCountUtil.release(byteBuf);
            this.byteBuf = null;
        }
    }

    private boolean isCacheExpire() {
        if (this.startTime == 0) {
            return true;
        }
        long nowTime = System.currentTimeMillis();
        return ((nowTime - startTime) > config.getResponseCacheTime());
    }

    public boolean isHaveCache(long requestId) {
        checkExpire();
        return this.requestId != 0 && this.requestId == requestId;
    }

    public void response() {
        this.ctx.writeAndFlush(this.byteBuf);
    }
}
